// Copyright Epic Games, Inc. All Rights Reserved.

#include "AbilitySystem/LyraAbilityTagRelationshipMapping.h"


#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraAbilityTagRelationshipMapping)

void ULyraAbilityTagRelationshipMapping::GetAbilityTagsToBlockAndCancel(const FGameplayTagContainer& AbilityTags, FGameplayTagContainer* OutTagsToBlock, FGameplayTagContainer* OutTagsToCancel) const
{
	/**
	 * 当这个能力去激活时，判断传入的能力的标签是否和阻塞和取消关系相映射，如果说传入的能力标签是映射关系里存在的，
	 * 我就可以去将这个能力标签所关联的阻塞或取消标签传出去。
	 */
	// Simple iteration for now

	// 现在进行简单迭代
	for (int32 i = 0; i < AbilityTagRelationships.Num(); i++)
	{
		const FLyraAbilityTagRelationship& Tags = AbilityTagRelationships[i];
		if (AbilityTags.HasTag(Tags.AbilityTag))
		{
			if (OutTagsToBlock)
			{
				/**
				 * Adds all the tags from one container to this container
				 * NOTE: From set theory, this effectively is the union of the container this is called on with Other.
				 *
				 * @param Other TagContainer that has the tags you want to add to this container
				 */

				/**
				 * AppendTags: 添加所有标签从一个容器到另一个容器。
				 */
				OutTagsToBlock->AppendTags(Tags.AbilityTagsToBlock);
			}
			if (OutTagsToCancel)
			{
				OutTagsToCancel->AppendTags(Tags.AbilityTagsToCancel);
			}
		}
	}
}

void ULyraAbilityTagRelationshipMapping::GetRequiredAndBlockedActivationTags(const FGameplayTagContainer& AbilityTags, FGameplayTagContainer* OutActivationRequired, FGameplayTagContainer* OutActivationBlocked) const
{
	/**
	 * 当能力想要激活时，判断传入的能力的标签是否和请求和取消关系相映射，如果说传入的映射关系是存在的，
	 * 则将这个能力激活时，所需要请求激活的能力标签和阻塞的能力标签传出去，这里是所需要激活自身和阻塞自身的标签。
	 */

	// Simple iteration for now
	
	// 现在进行简单迭代。
	for (int32 i = 0; i < AbilityTagRelationships.Num(); i++)
	{
		const FLyraAbilityTagRelationship& Tags = AbilityTagRelationships[i];
		if (AbilityTags.HasTag(Tags.AbilityTag))
		{
			if (OutActivationRequired)
			{
				OutActivationRequired->AppendTags(Tags.ActivationRequiredTags);
			}
			if (OutActivationBlocked)
			{
				OutActivationBlocked->AppendTags(Tags.ActivationBlockedTags);
			}
		}
	}
}

bool ULyraAbilityTagRelationshipMapping::IsAbilityCancelledByTag(const FGameplayTagContainer& AbilityTags, const FGameplayTag& ActionTag) const
{
	// Simple iteration for now

	// 现在进行简单迭代。
	for (int32 i = 0; i < AbilityTagRelationships.Num(); i++)
	{
		const FLyraAbilityTagRelationship& Tags = AbilityTagRelationships[i];

		if (Tags.AbilityTag == ActionTag && Tags.AbilityTagsToCancel.HasAny(AbilityTags))
		{
			return true;
		}
	}

	return false;
}

